package com.vlonjatg.progressability;

import com.vlonjatg.progressability.button.SuperButton;
import com.vlonjatg.progressability.loading.LoadingView;
import com.vlonjatg.progressability.util.AttrValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.components.AttrSet;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 各种状态下的Ability
 *
 * @since 2021-04-07
 */
public class ProgressDirectionalLayout extends DirectionalLayout implements ProgressLayout {
    private static final int RED_COLOR = 0xff0000;
    private static final int GREEN_COLOR = 0x00ff00;
    private static final int BLUE_COLOR = 0x0000ff;
    private static final int HEXADECIMAL = 16;
    private static final int ERRORSTATEBUTTONCOLOR = 30;
    private static final int OCTAL = 8;
    private static final String LOADING_TYPE = "loading_type";
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000f00, "dqh");
    private LayoutScatter layoutScatter;
    private final List<Component> contentViews = new ArrayList<>();
    private Element defaultBackground;
    private Component component;
    private Component errorState;
    private Image errorStateImageView;
    private Text errorStateTitleTextView;
    private Text errorStateContentTextView;
    private SuperButton errorStateButton;

    private Component emptyState;
    private Image emptyStateImageView;
    private Text emptyStateTitleTextView;
    private Text emptyStateContentTextView;

    private Component loadingState;

    private int loadingStateProgressBarWidth;
    private int loadingStateProgressBarHeight;
    private int loadingStateProgressBarColor;
    private int loadingStateBackgroundColor;

    private int emptyStateImageWidth;
    private int emptyStateImageHeight;
    private int emptyStateTitleTextSize;
    private Color emptyStateTitleTextColor;
    private int emptyStateContentTextSize;
    private Color emptyStateContentTextColor;
    private int emptyStateBackgroundColor;

    private int errorStateImageWidth;
    private int errorStateImageHeight;
    private int errorStateTitleTextSize;
    private Color errorStateTitleTextColor;
    private int errorStateContentTextSize;
    private Color errorStateContentTextColor;
    private Color errorStateButtonTextColor;
    private int errorStateButtonBackgroundColor;
    private int errorStateBackgroundColor;

    private String state = Constants.CONTENT;

    /**
     * 构造方法
     *
     * @param context 标题内容
     */
    public ProgressDirectionalLayout(Context context) {
        super(context);
    }

    /**
     * 构造方法
     *
     * @param context 标题内容
     * @param attrSet attr集
     */
    public ProgressDirectionalLayout(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init(attrSet);
    }

    /**
     * 构造方法
     *
     * @param context 标题内容
     * @param attrSet attr集
     * @param styleName 风格名
     */
    public ProgressDirectionalLayout(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(attrSet);
    }

    private void init(AttrSet attrSet) {
        layoutScatter = LayoutScatter.getInstance(getContext());

        loadingStateProgressBarWidth = AttrValue.get(attrSet, "loadingStateProgressBarWidth", 54);
        loadingStateProgressBarHeight = AttrValue.get(attrSet, "loadingStateProgressBarHeight", 54);
        loadingStateProgressBarColor = AttrValue.get(attrSet, "loadingProgressBarColor", Color.RED.getValue());
        loadingStateBackgroundColor = AttrValue.get(attrSet, "loadingBackgroundColor", Color.TRANSPARENT.getValue());

        emptyStateImageWidth = AttrValue.get(attrSet, "emptyImageWidth", 154);
        emptyStateImageHeight = AttrValue.get(attrSet, "emptyImageHeight", 154);
        emptyStateTitleTextSize = AttrValue.get(attrSet, "emptyTitleTextSize", 15);
        emptyStateTitleTextColor = AttrValue.get(attrSet, "emptyTitleTextColor", Color.BLACK);
        emptyStateContentTextSize = AttrValue.get(attrSet, "emptyContentTextSize", 14);
        emptyStateContentTextColor = AttrValue.get(attrSet, "emptyContentTextColor", Color.BLACK);
        emptyStateBackgroundColor = AttrValue.get(attrSet, "emptyBackgroundColor", Color.TRANSPARENT.getValue());

        errorStateImageWidth = AttrValue.get(attrSet, "errorImageWidth", 154);
        errorStateImageHeight = AttrValue.get(attrSet, "errorImageHeight", 154);
        errorStateTitleTextSize = AttrValue.get(attrSet, "errorTitleTextSize", 15);
        errorStateTitleTextColor = AttrValue.get(attrSet, "errorTitleTextColor", Color.BLACK);
        errorStateContentTextSize = AttrValue.get(attrSet, "errorContentTextSize", 14);
        errorStateContentTextColor = AttrValue.get(attrSet, "errorContentTextColor", Color.BLACK);
        errorStateButtonTextColor = AttrValue.get(attrSet, "errorButtonTextColor", Color.BLACK);
        errorStateButtonBackgroundColor = AttrValue.get(attrSet, "errorButtonBackgroundColor", Color.WHITE.getValue());
        errorStateBackgroundColor = AttrValue.get(attrSet, "errorBackgroundColor", Color.TRANSPARENT.getValue());

        defaultBackground = this.getBackgroundElement();
    }

    @Override
    public void showContent() {
        switchState(Constants.CONTENT, null);
    }

    @Override
    public void showContent(ParameterEntity parameterEntity) {
        switchState(Constants.CONTENT, parameterEntity);
    }

    @Override
    public void showLoading() {
        switchState(Constants.LOADING, null);
    }

    @Override
    public void showLoading(ParameterEntity parameterEntity) {
        switchState(Constants.LOADING, parameterEntity);
    }

    @Override
    public void showEmpty(ParameterEntity parameterEntity) {
        switchState(Constants.EMPTY, parameterEntity);
    }

    @Override
    public void showError(ParameterEntity parameterEntity) {
        switchState(Constants.ERROR, parameterEntity);
    }

    private void switchState(String switchState, ParameterEntity parameterEntity) {
        this.state = switchState;
        hideAllStates();
        switch (state) {
            case Constants.CONTENT:
                isNull(switchState, parameterEntity);
                break;
            case Constants.LOADING:
                isNull(switchState, parameterEntity);
                inflateLoadingView();
                break;
            case Constants.EMPTY:
                isNull(switchState, parameterEntity);
                inflateEmptyView();
                if (parameterEntity.getIconElement() != null) {
                    emptyStateImageView.setImageElement(parameterEntity.getIconElement());
                } else {
                    emptyStateImageView.setImageAndDecodeBounds(parameterEntity.getIconInt());
                }
                emptyStateTitleTextView.setText(parameterEntity.getTitle());
                emptyStateContentTextView.setText(parameterEntity.getDescription());
                break;
            case Constants.ERROR:
                isNull(switchState, parameterEntity);
                inflateErrorView();
                if (parameterEntity.getIconElement() != null) {
                    errorStateImageView.setImageElement(parameterEntity.getIconElement());
                } else {
                    errorStateImageView.setImageAndDecodeBounds(parameterEntity.getIconInt());
                }
                errorStateTitleTextView.setText(parameterEntity.getTitle());
                errorStateContentTextView.setText(parameterEntity.getDescription());
                errorStateButton.setText(parameterEntity.getButtonText().toUpperCase());
                errorStateButton.setClickedListener(parameterEntity.getButtonClickListener());
                break;
            default:
        }
    }

    private void isNull(String switchState, ParameterEntity parameterEntity) {
        if (switchState.equals(Constants.CONTENT)) {
            if (parameterEntity == null || parameterEntity.getIdsOfViewsNotToHide() == null) {
                setContentVisibility(true, Collections.emptyList());
            } else {
                setContentVisibility(true, parameterEntity.getIdsOfViewsNotToHide());
            }
        } else {
            if (parameterEntity == null || parameterEntity.getIdsOfViewsNotToHide() == null) {
                setContentVisibility(false, Collections.emptyList());
            } else {
                setContentVisibility(false, parameterEntity.getIdsOfViewsNotToHide());
            }
        }
    }

    private void hideAllStates() {
        hideLoadingView();
        hideEmptyView();
        hideErrorView();
        restoreDefaultBackground();
    }

    private void hideLoadingView() {
        if (loadingState != null) {
            loadingState.setVisibility(Component.HIDE);
        }
    }

    private void hideEmptyView() {
        if (emptyState != null) {
            emptyState.setVisibility(Component.HIDE);
        }
    }

    private void hideErrorView() {
        if (errorState != null) {
            errorState.setVisibility(Component.HIDE);
        }
    }

    private void restoreDefaultBackground() {
        this.setBackground(defaultBackground);
    }

    /**
     * 显示无参正常界面接口
     *
     * @param isVisible isVisible
     * @param skipIds skipIds
     */
    private void setContentVisibility(boolean isVisible, List<Integer> skipIds) {
        for (Component com : contentViews) {
            if (!skipIds.contains(com.getId())) {
                com.setVisibility(isVisible ? Component.VISIBLE : Component.HIDE);
            }
        }
    }

    private void inflateLoadingView() {
        if (loadingState == null) {
            component = layoutScatter.parse(ResourceTable.Layout_view_loading, null, false);
            loadingState = component.findComponentById(ResourceTable.Id_layout_loading);
            loadingState.setTag(Constants.LOADING);
            LoadingView loadingView = (LoadingView)
                    component.findComponentById(ResourceTable.Id_progress_bar_loading);
            loadingView.setBindStateChangedListener(loadingView);
            loadingView.setPaintcolor(loadingStateProgressBarColor);
            if (loadingStateProgressBarWidth != 0 || loadingStateProgressBarHeight != 0) {
                if (loadingStateProgressBarWidth > loadingStateProgressBarHeight) {
                    loadingView.setSize(loadingStateProgressBarHeight);
                } else {
                    loadingView.setSize(loadingStateProgressBarWidth);
                }
            }
            /*
             * 创建背景元素
             */
            ShapeElement shapeElement = new ShapeElement();
            /*
             * 设置颜色
             */
            HiLog.error(LABEL_LOG, Constants.LOG_FORMAT, "loadingStateBackgroundColor", loadingStateBackgroundColor);
            int red = (loadingStateBackgroundColor & RED_COLOR) >> HEXADECIMAL;
            int green = (loadingStateBackgroundColor & GREEN_COLOR) >> OCTAL;
            int blue = loadingStateBackgroundColor & BLUE_COLOR;
            shapeElement.setRgbColor(new RgbColor(red, green, blue));
            this.setBackground(shapeElement);
            DirectionalLayout.LayoutConfig layoutParams = new DirectionalLayout.LayoutConfig(
                    DirectionalLayout.LayoutConfig.MATCH_PARENT,
                    DirectionalLayout.LayoutConfig.MATCH_PARENT);
            addComponent(loadingState, layoutParams);
        } else {
            loadingState.setVisibility(VISIBLE);
        }
    }

    private void inflateEmptyView() {
        if (emptyState == null) {
            component = layoutScatter.parse(ResourceTable.Layout_view_empty, null, false);
            emptyState = component.findComponentById(ResourceTable.Id_layout_empty);
            emptyState.setTag(Constants.EMPTY);

            emptyStateImageView = (Image) component.findComponentById(ResourceTable.Id_image_icon);
            emptyStateTitleTextView = (Text) component.findComponentById(ResourceTable.Id_text_title);
            emptyStateContentTextView = (Text) component.findComponentById(ResourceTable.Id_text_description);
            emptyStateImageView.setWidth(emptyStateImageWidth);
            emptyStateImageView.setHeight(emptyStateImageHeight);

            emptyStateTitleTextView.setTextSize(emptyStateTitleTextSize, Text.TextSizeType.FP);
            emptyStateTitleTextView.setTextColor(emptyStateTitleTextColor);

            emptyStateContentTextView.setTextSize(emptyStateContentTextSize, Text.TextSizeType.FP);
            emptyStateContentTextView.setTextColor(emptyStateContentTextColor);
            /*
             * 创建背景元素
             */
            ShapeElement shapeElement = new ShapeElement();
            /*
             * 设置颜色
             */
            int red = (emptyStateBackgroundColor & RED_COLOR) >> HEXADECIMAL;
            int green = (emptyStateBackgroundColor & GREEN_COLOR) >> OCTAL;
            int blue = emptyStateBackgroundColor & BLUE_COLOR;
            shapeElement.setRgbColor(new RgbColor(red, green, blue));
            this.setBackground(shapeElement);

            DirectionalLayout.LayoutConfig layoutParams = new DirectionalLayout.LayoutConfig(
                    DirectionalLayout.LayoutConfig.MATCH_PARENT,
                    DirectionalLayout.LayoutConfig.MATCH_PARENT);

            addComponent(emptyState, layoutParams);
        } else {
            emptyState.setVisibility(VISIBLE);
        }
    }

    private void inflateErrorView() {
        if (errorState == null) {
            component = layoutScatter.parse(ResourceTable.Layout_view_error, null, false);
            errorState = component.findComponentById(ResourceTable.Id_layout_error);
            errorState.setTag(Constants.ERROR);

            errorStateImageView = (Image) component.findComponentById(ResourceTable.Id_image_icon);
            errorStateTitleTextView = (Text) component.findComponentById(ResourceTable.Id_text_title);
            errorStateContentTextView = (Text) component.findComponentById(ResourceTable.Id_text_description);
            errorStateButton = (SuperButton) component.findComponentById(ResourceTable.Id_button_retry);
            errorStateImageView.setWidth(errorStateImageWidth);
            errorStateImageView.setHeight(errorStateImageHeight);

            errorStateTitleTextView.setTextSize(errorStateTitleTextSize, Text.TextSizeType.FP);
            errorStateTitleTextView.setTextColor(errorStateTitleTextColor);

            errorStateContentTextView.setTextSize(errorStateContentTextSize, Text.TextSizeType.FP);
            errorStateContentTextView.setTextColor(errorStateContentTextColor);

            errorStateButton.setTextColor(errorStateButtonTextColor);
            /*
             * 创建背景元素
             */
            int buttonRed = (errorStateButtonBackgroundColor & RED_COLOR) >> HEXADECIMAL;
            int buttonGreen = (errorStateButtonBackgroundColor & GREEN_COLOR) >> OCTAL;
            int buttonBlue = errorStateButtonBackgroundColor & BLUE_COLOR;
            errorStateButton.setShapeColor(new RgbColor(buttonRed, buttonGreen, buttonBlue));
            errorStateButton.setShapeSelectorColor(new RgbColor(buttonRed - ERRORSTATEBUTTONCOLOR,
                    buttonGreen - ERRORSTATEBUTTONCOLOR, buttonBlue - ERRORSTATEBUTTONCOLOR));

            ShapeElement shapeElement = new ShapeElement();
            /*
             * 设置颜色
             */
            int red = (errorStateBackgroundColor & RED_COLOR) >> HEXADECIMAL;
            int green = (errorStateBackgroundColor & GREEN_COLOR) >> OCTAL;
            int blue = errorStateBackgroundColor & BLUE_COLOR;
            shapeElement.setRgbColor(new RgbColor(red, green, blue));
            this.setBackground(shapeElement);

            DirectionalLayout.LayoutConfig layoutParams = new DirectionalLayout.LayoutConfig(
                    DirectionalLayout.LayoutConfig.MATCH_PARENT,
                    DirectionalLayout.LayoutConfig.MATCH_PARENT);
            addComponent(errorState, layoutParams);
        } else {
            errorState.setVisibility(VISIBLE);
        }
    }

    @Override
    public void addComponent(Component childComponent) {
        super.addComponent(childComponent);
        contentViews.add(childComponent);
    }

    @Override
    public String getCurrentState() {
        return state;
    }

    @Override
    public boolean isContentCurrentState() {
        return state.equals(Constants.CONTENT);
    }

    @Override
    public boolean isLoadingCurrentState() {
        return state.equals(Constants.LOADING);
    }

    @Override
    public boolean isEmptyCurrentState() {
        return state.equals(Constants.EMPTY);
    }

    @Override
    public boolean isErrorCurrentState() {
        return state.equals(Constants.ERROR);
    }
}
